//
//  ZTNumberConvert.m
//  ZHYYTool
//
//  Created by MT-SW-005 on 2021/9/17.
//  Copyright © 2021 MT-SW-005. All rights reserved.
//

#import "ZTNumberConvert.h"
#import "ZTTypeConvert.h"
@implementation ZTNumberConvert

/*
*  计算字符串字节长度，返回计算的字节长度
*/
+(NSInteger) computeStringLength:(NSString *)string
{
    NSInteger length = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    return length;
    
}
 
 
/*
*  字符串转换为二进制字符串
*/
+(NSString *)stingToBinary:(NSString *)string
{
    NSData *myData = [string dataUsingEncoding:NSUTF8StringEncoding];
    Byte *bytes = (Byte *)[myData bytes];

    NSString *hexStr=@"";
    for(int i=0; i<[myData length]; i++)
    {
        NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];
        if([newHexStr length]==1)
            hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];
        else
            hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr];
    }
    
    return [self hexToBinary:hexStr];
    
}
 

/*
*  二进制转换为字符串，暂不可用
*/
//+ (NSString *)binaryToString:(NSData *)data{
//    return @" not implementation";
//}
 


/*
*  字符串转换为十六进制
*/
+ (NSString *)stringtoHex:(NSString *)string
{
    NSData *myD = [string dataUsingEncoding:NSUTF8StringEncoding];
    Byte *bytes = (Byte *)[myD bytes];

    NSString *hexStr = @"";
    for(int i=0; i<[myD length]; i++)
    {
        NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];
        if([newHexStr length]==1)
            hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];
        else
            hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr];
    }
    return hexStr;
}
 
 

/*
*  十六进制转换为字符串
*/
+ (NSString *)hexToString:(NSString *)hexString
{
    if (!hexString || [hexString length] == 0) {
        return nil;
    }
    NSLog(@"line : %d, func: %s ",__LINE__, __func__);
    char *myBuffer = (char *)malloc((int)[hexString length] / 2 + 1);
    bzero(myBuffer, [hexString length] / 2 + 1);
    for (int i = 0; i < [hexString length] - 1; i += 2) {
        unsigned int anInt;
        NSString * hexCharStr = [hexString substringWithRange:NSMakeRange(i, 2)];
        NSScanner * scanner = [[[NSScanner alloc] initWithString:hexCharStr] init];
        [scanner scanHexInt:&anInt];
        myBuffer[i / 2] = (char)anInt;
    }
    NSString *unicodeString = [NSString stringWithCString:myBuffer encoding:4];

    return unicodeString;
}
 
 
/*
*  十六进制转换为二进制
*/
+(NSString *)hexToBinary:(NSString *)hex
{
    NSMutableDictionary  *hexDic = [[NSMutableDictionary alloc] init];
    hexDic = [[NSMutableDictionary alloc] initWithCapacity:16];
    [hexDic setObject:@"0000" forKey:@"0"];
    [hexDic setObject:@"0001" forKey:@"1"];
    [hexDic setObject:@"0010" forKey:@"2"];
    [hexDic setObject:@"0011" forKey:@"3"];
    [hexDic setObject:@"0100" forKey:@"4"];
    [hexDic setObject:@"0101" forKey:@"5"];
    [hexDic setObject:@"0110" forKey:@"6"];
    [hexDic setObject:@"0111" forKey:@"7"];
    [hexDic setObject:@"1000" forKey:@"8"];
    [hexDic setObject:@"1001" forKey:@"9"];
    [hexDic setObject:@"1010" forKey:@"A"];
    [hexDic setObject:@"1011" forKey:@"B"];
    [hexDic setObject:@"1100" forKey:@"C"];
    [hexDic setObject:@"1101" forKey:@"D"];
    [hexDic setObject:@"1110" forKey:@"E"];
    [hexDic setObject:@"1111" forKey:@"F"];
    [hexDic setObject:@"1010" forKey:@"a"];
    [hexDic setObject:@"1011" forKey:@"b"];
    [hexDic setObject:@"1100" forKey:@"c"];
    [hexDic setObject:@"1101" forKey:@"d"];
    [hexDic setObject:@"1110" forKey:@"e"];
    [hexDic setObject:@"1111" forKey:@"f"];
    NSMutableString *binaryString = [[NSMutableString alloc] init];
    
    for (int i=0; i<[hex length]; i++) {
        NSRange rage;
        rage.length = 1;
        rage.location = i;
        NSString *key = [hex substringWithRange:rage];
        binaryString = [NSMutableString stringWithFormat:@"%@%@",binaryString,[NSString stringWithFormat:@"%@",[hexDic objectForKey:key]]];
    }
    return binaryString;
}
 
 
/*
*  十进制转换为十六进制
*/
+ (NSString *)decimalSystemToHex:(int64_t)tmpid
{
 NSString *nLetterValue;
 NSMutableString *str = [NSMutableString string];
 int64_t ttmpig;
 while (tmpid > 0) {
     ttmpig = tmpid%16;
     tmpid = tmpid/16;
     switch (ttmpig)
     {
         case 10:
             nLetterValue =@"A";break;
         case 11:
             nLetterValue =@"B";break;
         case 12:
             nLetterValue =@"C";break;
         case 13:
             nLetterValue =@"D";break;
         case 14:
             nLetterValue =@"E";break;
         case 15:
             nLetterValue =@"F";break;
         default:
             nLetterValue = [NSString stringWithFormat:@"%lld",ttmpig];
     }
     [str appendString:nLetterValue];
     if (tmpid == 0) {
         break;
     }
 }
 NSString *result = [ZTTypeConvert reverseString:str];
 return result;
}
 


/*
*  十进制转换为八进制
*/
+(NSString *)decimalSystemToOctal:(int64_t)tmpid
{
    NSString *nLetterValue;
    NSMutableString *str = [NSMutableString string];
    int64_t ttmpig;
    while (tmpid > 0) {
        ttmpig = tmpid%8;
        tmpid = tmpid/8;
        nLetterValue = [NSString stringWithFormat:@"%lld",ttmpig];
        [str appendString:nLetterValue];
        if (tmpid == 0) {
            break;
        }
    }
    NSString *result = [ZTTypeConvert reverseString:str];
    return result;
}


/*
*  十进制转换为二进制
*/
+ (NSString *)decimalSystemToBinary:(NSString *)decimal
//{
//    BOOL negative = NO;
//    int num = [decimal intValue];
//    if (num <0){
//        negative =YES;
//        num=abs(num);
//    }
//    int remainder = 0; //余数
//    int divisor = 0;  //除数
//
//    NSString * prepare = @"";
//
//    while (true)
//    {
//        remainder = num%2;
//        divisor = num/2;
//        num = divisor;
//        prepare = [prepare stringByAppendingFormat:@"%d",remainder];
//
//        if (divisor == 0)
//        {
//            break;
//        }
//    }
//
//    NSString * result = @"";
//    for (long i = prepare.length - 1; i >= 0; i --)
//    {
//        result = [result stringByAppendingFormat:@"%@",
//                  [prepare substringWithRange:NSMakeRange(i , 1)]];
//    }
//    if (negative){
//        NSMutableString * r = [NSMutableString stringWithFormat:@"-%@",result];
//        return r;
//    }
//    return result;
//}
{
    NSString *nLetterValue;
     NSMutableString *str = [NSMutableString string];
     int64_t ttmpig;
     int64_t tmpid = [decimal longLongValue];
     while (tmpid > 0) {
         ttmpig = tmpid%2;
         tmpid = tmpid/2;
         nLetterValue = [NSString stringWithFormat:@"%lld",ttmpig];
         
         [str appendString:nLetterValue];
         if (tmpid == 0) {
             break;
         }
     }
     NSString *result = [ZTTypeConvert reverseString:str];
     return result;
}


/*
*  二进制转换为十进制
*/
+ (NSString *)binaryToDecimalSystem:(NSString *)binary
{
    int temp = 0;
    long temp1 = 0;
    long ll = 0;
    for (int i = 0; i < binary.length; i ++)
        {
            temp = [[binary substringWithRange:NSMakeRange(i, 1)] intValue];
            temp1 = temp * powf(2, binary.length - i - 1);
            ll += temp1;
        }
    NSString * result = [NSString stringWithFormat:@"%ld",ll];
    return result;
}
 
 
/*
*  十六进制转换为十进制
*/
+(NSString*)hexToDecimalSystem:(NSString *)hex
{
    NSString *temp = @"";
    long temp1 = 0;
    long ll = 0;
    for (int i = 0; i < hex.length; i ++)
    {
        temp = [[hex substringWithRange:NSMakeRange(i, 1)] uppercaseString];
        int n = 0;
        if ([temp isEqualToString:@"A"]) {
            n = 10;
        }else if ([temp isEqualToString:@"B"]) {
            n = 11;
        }else if ([temp isEqualToString:@"C"]) {
            n = 12;
        }else if ([temp isEqualToString:@"D"]) {
            n = 13;
        }else if ([temp isEqualToString:@"E"]) {
            n = 14;
        }else if ([temp isEqualToString:@"F"]) {
            n = 15;
        }else{
            n =[temp intValue];
        }
        temp1 = n * powf(16, hex.length - i - 1);
        ll += temp1;
    }
    NSString * result = [NSString stringWithFormat:@"%ld",ll];
    return result;
}


/*
* 八进制转换为十进制
*/
+(NSString*)octalToDecimalSystem:(NSString *)octal
{
    int temp = 0;
    long temp1 = 0;
    long ll = 0;
    for (int i = 0; i < octal.length; i ++){
         temp = [[octal substringWithRange:NSMakeRange(i, 1)] intValue];
         temp1 = temp * powf(8, octal.length - i - 1);
         ll += temp1;
     }
     NSString * result = [NSString stringWithFormat:@"%ld",ll];
     return result;
}



/*
*  二进制转十六进制,私有方法，暂时不支持外部调用
*/
+ (NSString *)BinaryToHex:(NSData *)data
{
    if (!data) {
        return nil;
    }
    
    NSString * binary = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    
    NSMutableDictionary  *hexDic = [[NSMutableDictionary alloc] init];
    hexDic = [[NSMutableDictionary alloc] initWithCapacity:16];
    [hexDic setObject:@"0" forKey:@"0000"];
    [hexDic setObject:@"1" forKey:@"0001"];
    [hexDic setObject:@"2" forKey:@"0010"];
    [hexDic setObject:@"3" forKey:@"0011"];
    [hexDic setObject:@"4" forKey:@"0100"];
    [hexDic setObject:@"5" forKey:@"0101"];
    [hexDic setObject:@"6" forKey:@"0110"];
    [hexDic setObject:@"7" forKey:@"0111"];
    [hexDic setObject:@"8" forKey:@"1000"];
    [hexDic setObject:@"9" forKey:@"1001"];
    [hexDic setObject:@"A" forKey:@"1010"];
    [hexDic setObject:@"B" forKey:@"1011"];
    [hexDic setObject:@"C" forKey:@"1100"];
    [hexDic setObject:@"D" forKey:@"1101"];
    [hexDic setObject:@"E" forKey:@"1110"];
    [hexDic setObject:@"F" forKey:@"1111"];
    
    NSMutableString *hexString = [[NSMutableString alloc] init];
    
    for (int i=0; i<[binary length]; i+=4) {
        NSRange rage;
        rage.length = 4;
        rage.location = i;
        NSString *key = [binary substringWithRange:rage];
        hexString = [NSMutableString stringWithFormat:@"%@%@",hexString,[NSString stringWithFormat:@"%@",[hexDic objectForKey:key]]];
    }
    
    return hexString;
}


/*
*  二进制转十六进制
*/
+ (NSString *)binaryToHex:(NSString*)binaryString
{
    NSString *data = [self binaryToDecimalSystem:binaryString];
    NSLog(@"2-->10:%@",data);
    int decimalSystem = [data intValue];
    NSString *result = [self decimalSystemToHex:decimalSystem];
    return  result;
}

 

/*
* 十六进制转换十进制 可以接受的十六进制格式为:"7B","7b","0X7b"
*/
+ (NSString *)hexToDecimalSystem2:(NSString*)hex
{
    //十六进制转换二进制
    NSString *data = [self hexToBinary:hex];
    //二进制转换为十进制
    NSString *result = [self binaryToDecimalSystem:data];
    return result;
}


/*
*  十六进制转换十进制,可以接受的十六进制格式为:"0X7b"
*/
+ (int) hexStrToInt:(NSString*)hexStr
{
    hexStr = [hexStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    
    int result = 0;
    int index = 0;
    
    NSString* str = [hexStr uppercaseString];
    
    if ([str rangeOfString:@"0X"].length > 0) {
        index = 2;
    } else {
        NSRange range = [hexStr rangeOfString:@"^[0-9A-F]+$" options:NSRegularExpressionSearch];
        
        if (range.length <= 0) {
            result = 0;
            return result;
        }
    }
    
    for (int i = index; i < [str length]; i++)
    {
        int charValue = [str characterAtIndex:i];
        
        if ((charValue >= '0') && (charValue <= '9'))
        {
            result += (charValue - '0') * pow(16, ([str length] - 1 -i));
        }
        else if ((charValue >= 'A') && (charValue <= 'F'))
        {
            result += (charValue - 'A' + 10) * pow(16, ([str length] - 1 -i));
        }
    }
    
    return result;
}

/* =====================================================================================*/


/*
*  原码，反码，补码转换
*/
+ (NSMutableDictionary*) complementConvertWithNumber:(int)n
{
    int m,a[10],i = 0,y[10000],f[10000],b[10000],j,k;
    //printf("请输入一个整数:");
    //scanf("%d",&n);
    m = abs(n);
    while (m!=0)
     {
         a[i] = m%2;
         m = m/2;
         i = i+1;
     }
     if (n>=0)
     {
         for(j=0; j<i; j++) y[j]=a[j];
         if ((j+1)%8!=0) for(;(j+1)%8!=0;j++)  y[j]=0;
         y[j] = 0;
         for(k=0;k<=j;k++)
         {
             f[k]=y[k];
             b[k]=y[k];
         }
     }
     else
     {
         int w=0;
         for(j=0;j<i;j++)    y[j]=a[j];
         if ((j+1)%8!=0) for(;(j+1)%8!=0;j++)  y[j]=0;y[j]=1;
         for(k=0;k<j;k++)    if(y[k]) f[k]=0;else f[k]=1;f[k]=1;
         for( k=0;k<j;k++)    {if (k==0)b[k]=f[k]+1;else b[k]=f[k]+w;if (b[k]==2){b[k]=0;w=1;}else w=0;}b[k]=1;
     }
    
    //原码
    NSMutableArray * originalCode=[NSMutableArray array];
    for(k=j;k>=0;k--){
        [originalCode addObject:[NSNumber numberWithInt:y[k]]];
    }
    
    //反码;
    NSMutableString  *radixMinusOneComplement=[NSMutableString string];
    for(k=j;k>=0;k--)
    {
        [radixMinusOneComplement appendFormat:@"%d",f[k]];
    }
    
    //补码
    NSMutableArray *complement=[NSMutableArray array];
    for(k=j;k>=0;k--)
    {
       [complement addObject:[NSNumber numberWithInt:b[k]]];
    }
    NSDictionary *codeDict=@{
        @"originalCode":originalCode,
        @"radixMinusOneComplement":radixMinusOneComplement,
        @"complement":complement
    };
    
    return [NSMutableDictionary dictionaryWithDictionary:codeDict];
}




/*
*  将补码对应的原码转换为十进制
*/
+(NSMutableString *)convertComplementToint:(NSMutableArray *)binary
{
    NSNumber *num1 = @1;
    NSNumber *num0 = @0;
    for (int i =0; i<[binary count]; i++) {
        [binary replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:[binary[i] intValue]]];
    }
   
    NSString *result;
    if([binary objectAtIndex:0] == num0){
        NSMutableString *binaryStr = [NSMutableString string];
        for (NSNumber *numStr in binary){
            [binaryStr appendFormat:@"%@",numStr];
        }
        NSString *decStr = [self binaryToDecimalSystem:binaryStr];
        result = [NSString stringWithString:decStr];
    } else if ([binary objectAtIndex:0] == num1) {
        for (int i=0; i<[binary count]; i++ ){
            if ([binary objectAtIndex:0] == num1){
                if (i > 0){
                    if ([binary objectAtIndex:i] == num1){
                        [binary replaceObjectAtIndex:i withObject:num0];
                    }else if([binary objectAtIndex:i] == num0){
                        [binary replaceObjectAtIndex:i withObject:num1];
                    };
                }
            }
        }
        
        if ([binary objectAtIndex:([binary count]-1)] == num0){
            [binary replaceObjectAtIndex:([binary count]-1) withObject:num1];
        }
        else{
            NSMutableString *binaryStr1 = [NSMutableString string];
            for (NSNumber *numStr in binary){
                [binaryStr1 appendFormat:@"%@",numStr];
            }
            NSString *r1 = [self binaryToDecimalSystem:binaryStr1];
          
            int r2 = [r1 intValue]+1;
            NSString *r3 = [self decimalSystemToBinary:[NSString  stringWithFormat:@"%d",r2]];
            NSMutableArray *r4 = [ZTTypeConvert stringToArray:r3];
           
            [binary removeAllObjects];
            [binary addObjectsFromArray:r4];
        }
       
        [binary replaceObjectAtIndex:0 withObject:num0];
       
        NSMutableString *binaryStr = [NSMutableString string];
        for (NSNumber *numStr in binary){
            [binaryStr appendFormat:@"%@",numStr];
        }
        
        NSString *decStr = [self binaryToDecimalSystem:binaryStr];
        result = [NSString stringWithFormat:@"-%@",decStr];
    }
    return [NSMutableString stringWithString:result];
}


// 511 -> 100%
+ (NSString*)numberTopercentage:(NSString *)num withDenominator:(float)denominator
{
    NSMutableDictionary *codeDict = [self complementConvertWithNumber:[num intValue]];
    NSMutableArray *arrayData = [NSMutableArray array];
    arrayData = [codeDict objectForKey:@"complement"];
    NSMutableString *result = [self convertComplementToint:arrayData];
    NSString *percentageResult = [NSString stringWithFormat:@"%.2f%%",([result floatValue] / denominator) * 100.00];
    return percentageResult;
}


// 100% -> 511
+ (NSString *)percentageToNumber:(NSString*)percentageStr withDenominator:(float)denominator
{
    NSMutableString *percentage = [NSMutableString string];
    [percentage appendString:percentageStr];
    NSString *p1 = [percentage stringByReplacingOccurrencesOfString:@"%" withString:@""];
    int intNumResult = (int)(([p1 floatValue ]) * denominator /100.00 +0.5);
    NSString *resultNum =[NSString stringWithFormat:@"%d",intNumResult];
    return resultNum;
}

// 65025 -> -511  65535 -> -1
+(NSString* )conversionNum:(NSString *)decNum
{
    NSString *str = [self decimalSystemToBinary:decNum];
    NSMutableArray *binaryArray = [ZTTypeConvert stringToArray:str];
    NSMutableString *result = [self convertComplementToint:binaryArray];
    return result;
}


// -511 -> 65025  -1 -> 255
//获取数字对应补码再转化为数字
+ (NSString *)conversionNum2:(NSString*)decNum
{
    NSMutableDictionary *codeDict = [self complementConvertWithNumber:[decNum intValue]];
    NSMutableArray *arrayData = [NSMutableArray array];
    arrayData = [codeDict objectForKey:@"complement"];
    NSMutableString *binaryStr =[NSMutableString string];
    for (NSNumber *  numStr in arrayData){
        [binaryStr appendFormat:@"%@",numStr];
    }
    NSString *decStr = [self binaryToDecimalSystem:binaryStr];
    NSString *result = [NSString stringWithFormat:@"%@",decStr];
    return result;
}

@end
